How it's wired Tepna
← the -Dex suite · node wiring

💗PulseDex

PulseDex senses one signal — the beat-to-beat RR interval — and turns it into a full HRV suite. Because it works on genuine RR (not a 1 Hz proxy), its time/frequency/Poincaré metrics are validated HRV, the same family ECGDex produces.

Signal sensed
RR intervalsbeat-to-beat, milliseconds
Device
Polar Verity Senseoptical armband · + any RR source
Input format
RR CSV+ Welltory-format CSV
Produces
Full HRV + ANS read→ ganglior.node-export
01 — WHAT IT'S FOR

A single-signal receptor

Read the suite as a reflex arc: receptors → relay → integration → insight. PulseDex is an afferent receptor — it does exactly one transduction well and reports inward. It never reaches into another node; cross-signal work happens only through the Ganglior export, consumed by the Integrator.

🧠
One signal per node. PulseDex senses rr intervals and nothing else. If you’re tempted to sense a second signal, that’s a second node — fusion is the Integrator’s job, never a receptor’s.
02 — THE WIRING

The file stack

PulseDex is built from external *.js files referenced by PulseDex.src.html and bundled to a standalone PulseDex.html. Dependencies point downhill only — UI → DSP → Core — and each file owns exactly one job. Edit the .js + .src.html, never the bundle; re-bundle after changes.

DSP
pulsedex-dsp.jsDSP
RR signal math: time- & frequency-domain HRV, Poincaré, Welltory-calibrated estimates, advanced metrics (Lomb–Scargle, DFA α1, SampEn, fragmentation, PRSA), artifact correction and a recording classifier.
Core
kernel-constants.jsCore · shared
The frozen physiology kernel — one source of truth for every cross-fleet threshold, plus a content-derived hash stamped into each export so two bundles built on different rulebooks can’t silently “agree” when fused.
ganglior-provenance.jsCore · shared
Loaded first — installs the read-hook that makes every export attributable to the exact code + inputs that produced it (the buildHash provenance stamp). 100% local.
metric-registry.jsCore · shared
The shared half of the evidence system: the badge SHAPE, depth tiering and the injected badge CSS. The per-node registry below supplies the DATA, so a Validated dot looks identical in every node.
crossnight-envelope.jsCore · shared
The shared, versioned shape (ganglior.crossnight v1.0) every node emits and the Integrator reads — the container, not the math (the local crossNight() stats stay per-node).
pulsedex-registry.jsCore
Per-metric DATA map. RR-based HRV grades as validated here (unlike OxyDex’s 1 Hz proxies); labels mirror the cross defs.
Render · UI
pulsedex-render.jsRender · UI
DOM/SVG builders: context banner, night-trend graphs, KPI strip, ANS bars, the full metrics table and the canonical Welltory-format table.
pulsedex-overview.jsRender · UI
The hero overview: ANS-age + VO₂max/BP projections, body-composition profile, and the key-metrics summary block (HRVDex-matched).
App · glue
pulsedex-app.jsApp · glue
Orchestration & glue: theme, scroll-spy, RR + Welltory ingest, the calculate() pipeline, exports and reset.
Fusion · export
pulsedex-cross.jsFusion · export
The byte-identical multi-night analytics helper — trend, z-scores, significance.
🕒
The Clock Contract. PulseDex stamps every record as floating wall-clock tMs (local civil time encoded as if UTC) and reads it back with getUTC* — so the recording reads identically in any viewer’s timezone, and two devices recording the same minute land on the same tMs. parseTimestamp is duplicated locally by design.
03 — HOW IT'S ACHIEVED

From file drop to Ganglior event

The pipeline is the same shape across the suite: ingest → parse on the canonical clock → compute in DSP → grade & render in UI → emit onto the bus. No number is computed in the render layer; it asks DSP for the value and the registry for how to show it.

Load RR or Welltory CSV

Drop a beat-to-beat RR file or a Welltory export. PulseDex auto-classifies the recording type.

pulsedex-app.js → ingest

Stamp + correct beats

Timestamps become floating tMs; ectopic/missed beats are detected and corrected before any HRV is computed.

parseTimestamp() + artifact correction

Compute the HRV suite

Time-domain, Lomb–Scargle frequency-domain (handles uneven sampling), Poincaré, DFA α1, SampEn, fragmentation and PRSA — all from real RR.

pulsedex-dsp.js → calculate()

Render + personalize

Render draws KPIs, ANS bars and tables; the overview projects ANS-age / VO₂max against the user profile. Edits re-derive live via reRender().

pulsedex-render.js + overview.js

Emit onto Ganglior

Export the node-export JSON so the Integrator can fuse PulseDex HRV with oximetry and glucose.

ganglior.node-export
04 — HOW MUCH TO TRUST IT

The evidence ladder

Every metric PulseDex surfaces carries an evidence grade — a non-hue badge whose fill is the confidence ladder: solid bullseye for a raw reading, down to a dashed ring for a friendly estimate. A measurement and a projection must never look alike. Grades live in pulsedex-registry.js, the one source of truth.

Measured Pulse HR · mean / median / min / max RR · coverage & quality
Validated rMSSD · SDNN · LF/HF · SD1 / SD2 · Poincaré — genuine RR-based HRV
Emerging DFA α1 · SampEn · fragmentation · PRSA
Experimental Composite stability indices
Heuristic ANS-age · VO₂max · BP proxies
05 — LIMITATIONS & CONSIDERATIONS

What it can and can't say

Honesty is architectural: a guess is never dressed as a measurement, a missing value stays null rather than fabricated, and confidence is kept separate from signal quality. The node-specific caveats:

Optical PPI under motionnote

When fed wrist-optical pulse intervals, accuracy drops under movement. ECG RR is the more precise source; PulseDex flags low-quality stretches.

Real RR → real HRVby design

Because the input is true beat-to-beat timing, the core HRV family is graded validated — the key distinction from OxyDex’s pulse-rate proxies.

Estimates are estimatescaution

ANS-age, VO₂max and BP are heuristic projections from HRV — useful as a personal trend, not a clinical value.

Uneven sampling handlednote

Frequency-domain HRV uses Lomb–Scargle, so it tolerates the irregular spacing inherent to a beat series rather than forcing resampling.

06 — HOW TO USE IT

For the curious, and for the next coder

📂

Open the instrument

PulseDex is one self-contained file. Open PulseDex.html in any browser — online, offline, or from file://. Nothing installs, nothing phones home.

Open PulseDex →
📥

Drop your recording

Drag a Polar Verity Sense export (rr csv) onto the upload zone. It’s read in-browser and turned into metrics on your device alone.

🎚️

Read at your depth

Start in Core for the headline readiness and a plain-language line. Step up to Advanced for full tables and charts, or Research for composites and the full dump. Each metric’s evidence dot tells you how far to trust it.

🔀

Export onto Ganglior

Export a ganglior.node-export JSON to feed the Integrator, or to upgrade a peer node’s read. Events carry a wall-clock t; consumers reconstruct absolute time from the recording start.

PulseDex reference guide →
🛠️

If you’re changing it

Edit the pulsedex-*.js files or PulseDex.src.htmlnever the bundled PulseDex.html — then re-bundle. Run Dex-Test-Suite.html until all-green, and verify-provenance.html after re-bundling.